梦入琼楼寒有月,行过石树冻无烟

D3 坐标轴与刻度(Axes)

坐标轴(Axes),通常在一些学术图标中进行使用,很多情况下的图表数据都是经过 比例尺(Scale) 来计算出的大小与坐标位置,可以通过使用刻度尺来进行标注,主要作用是辅助读者进行阅读,可以通过下图来感受到明显的差距:

参数与坐标轴

ID DA FA
Axes 设置比例尺提供人类观感友好的标尺刻度
d3.axisTop 创建一个刻度尺在的坐标轴生成器
d3.axisRight 创建一个刻度尺在的坐标轴生成器
d3.axisBottom 创建一个刻度尺在的坐标轴
d3.axisLeft 创建一个刻度尺在的坐标轴
axis 为指定的选择器生成一个坐标轴
axis.scale 设置坐标轴的比例尺
axis.ticks 自定义刻度的显示方式及格式化刻度
axis.tickArguments 自定义如何生成刻度或格式化刻度
axis.tickValues 指定固定的刻度值
axis.tickFormat 指定固定的刻度单位
axis.tickSize 设置刻度大小
axis.tickSizelnner 设置内刻度大小
axis.tickSizeOuter 设置外侧,刻度大小
axis.tickPadding 设置刻度和刻度文本之间的间距

d3 version 3 和 d3 version 4 的区别就是在 v3 中除了需要绘制比例尺和刻度尺之外,还需要写入其CSS样式,极大的方便了开发者在绘制中的时间。

需要注意的是,在 d3 version4 中将 v3 scale.linear 改为 scaleLinaer。除此之外,还将 orient,替换成了**d3.axisBottom(xScale)**。

bottom and left


通过使用 d3.axisBottom以及d3.axisLeat来构建一个坐标轴,其坐标轴构建完成后一定是关联起来的而并非是分开的,因此我们通过使用线性比例尺来通过center中的数据来决定刻度的最大值和最小值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
var padding = {
width: 700,
height: 700,
xAxisWidth: 500,
yAxisWidth: 500,
right: 30,
bottom: 30,
left: 130
}
var center= [
[1,1]
]
/*
* 选择 id 为 demo 的元素
* 设置 width.height 为 700
*/
var svg = d3.select("#demo")
.append("svg")
.attr("width",padding.width)
.attr("height", padding.height)

/*
分别定义 x/y 轴比例尺 xScale 、 yScale
并根据数据来决定比例尺数值中的数据
*/
var xScale = d3.scaleLinear()
.domain([0, 1 * d3.max(center, function (d) {
return d[1]
})])
.range([0, padding.xAxisWidth])

var yScale = d3.scaleLinear()
.domain([0,1 * d3.max(center, function (d) {
return d[1]
})])
.range([0, padding.yAxisWidth])

/*
* 分别选择 svg 并添加 g 元素
* 分别计算出 xScale 和 yScale 位置
* 将坐标轴位置定义为 Bottom、Left等,分别为 x 轴和 y 轴方向。
*/
d3.select("svg")
.append("g")
.attr("transform","translate(" + padding.left + "," + (padding.height - padding.bottom) + ")")
.call(d3.axisBottom(xScale))

d3.select("svg")
.append("g")
.attr("transform", "translate(" + padding.left + "," + (padding.height - padding.bottom - padding.yAxisWidth) + ")")
.call(d3.axisLeft(yScale))

bottom


如果你觉得上述的 code 太复杂,只想要一个坐标轴,那我们可以单独使用axisBottom来绘制一个刻度为底部方向的坐标轴。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
var padding = {
width: 700,
height: 700,
xAxisWidth: 500,
yAxisWidth: 500,
right: 30,
bottom: 30,
left: 130
}
var center= [
[1,1]
]
/*
* 选择 id 为 demo 的元素
* 设置 width.height 为 700
*/
var svg = d3.select("#demo")
.append("svg")
.attr("width",padding.width)
.attr("height", padding.height)

/*
分别定义 x/y 轴比例尺 xScale
并根据数据来决定比例尺数值中的数据
*/
var xScale = d3.scaleLinear()
.domain([0, 1 * d3.max(center, function (d) {
return d[1]
})])
.range([0, padding.xAxisWidth])

/*
* 定义坐标轴
* ticks
* 自定义刻度的显示方式及格式化刻度
*/
var xAxis = d3.axisBottom(xScale)

d3.select("svg")
.append("g")
.attr("transform","translate(" + padding.left + "," + (padding.height - padding.bottom) + ")")
.call(xAxis)

刻度

数值

ticks


假设没有使用 ticks参数的比例尺刻度为0.0、0.1、0.2、0.3、0.4、0.5、0.6、0.7、0.8、0.9、1.0,那么通过ticks则会格式化输出为0.0、0.2、0.4、0.6、0.8、1.0,即自定义刻度的显示方式并格式化刻度

ticks 方法也可以被看做是 axis.tickArguments的简写,如下述 code 的例子为ticks(5),则可以被看做是axis.tickArguments([10])

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
var padding = {
width: 700,
height: 700,
xAxisWidth: 500,
yAxisWidth: 500,
right: 30,
bottom: 30,
left: 130
}
var center= [
[1,1]
]
/*
* 选择 id 为 demo 的元素
* 设置 width.height 为 700
*/
var svg = d3.select("#demo")
.append("svg")
.attr("width",padding.width)
.attr("height", padding.height)

/*
分别定义 x/y 轴比例尺 xScale 、 yScale
并根据数据来决定比例尺数值中的数据
*/
var xScale = d3.scaleLinear()
.domain([0, 1 * d3.max(center, function (d) {
return d[1]
})])
.range([0, padding.xAxisWidth])

var yScale = d3.scaleLinear()
.domain([0,1 * d3.max(center, function (d) {
return d[1]
})])
.range([0, padding.yAxisWidth])

/*
* 定义坐标轴
* ticks
* 自定义刻度的显示方式及格式化刻度
*/
var xAxis = d3.axisBottom(xScale)
.ticks(5)

var yAxis = d3.axisLeft(yScale)
.ticks(5)
/*
* 分别选择 svg 并添加 g 元素
* 分别计算出 xScale 和 yScale 位置
* 将坐标轴位置定义为 Bottom、Left等,分别为 x 轴和 y 轴方向。
*/
d3.select("svg")
.append("g")
.attr("transform","translate(" + padding.left + "," + (padding.height - padding.bottom) + ")")
.call(xAxis)


d3.select("svg")
.append("g")
.attr("transform", "translate(" + padding.left + "," + (padding.height - padding.bottom - padding.yAxisWidth) + ")")
.call(yAxis)

tickValues

tickValues 为指定刻度数值,如原始数值为1,2,3,4,5,6,7,8,9,10,当tickValues 内参数值为[0, 2, 4, 6, 8, 10]时,则刻度尺将会是数组内的数据。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
var padding = {
width: 700,
height: 700,
xAxisWidth: 500,
yAxisWidth: 500,
right: 30,
bottom: 30,
left: 130
}
var center= [
[1,1]
]
/*
* 选择 id 为 demo 的元素
* 设置 width.height 为 700
*/
var svg = d3.select("#demo")
.append("svg")
.attr("width",padding.width)
.attr("height", padding.height)

/*
分别定义 x/y 轴比例尺 xScale
并根据数据来决定比例尺数值中的数据
*/
var xScale = d3.scaleLinear()
.domain([0, 1 * d3.max(center, function (d) {
return d[1]
})])
.range([0, padding.xAxisWidth])

/*
* 定义坐标轴
* ticks
* 自定义刻度的显示方式及格式化刻度
*/
var xAxis = d3.axisBottom(xScale)
/*
tickValue([value])
如果数据为 0~1 的话,那么通过使用 tickValues 则会输出
-> 0, 0.2, 0.4, 0.6, 0.8, 1
*/
.tickValues([0, 0.2, 0.4, 0.6, 0.8, 1])

d3.select("svg")
.append("g")
.attr("transform","translate(" + padding.left + "," + (padding.height - padding.bottom) + ")")
.call(xAxis)

tickFormat

如果指定了 tickFormat 则设置刻度的文字标签的格式化方法,可以通过使用 tickFormat 来为刻度添加单位,如:

1
2
3
var xAxis = d3.axisBottom(xScale)
.ticks(2)
.tickFormat(d => d+ " day")

长度

tickSize


tickSize 主要用于设置刻度外侧(outer)和内侧(inner)的高度,但需要注意的是在 d3 version3 版本中 tickSize 可以分别设置内侧和外侧的高度,但在 v4中被取消了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
var padding = {
width: 700,
height: 700,
xAxisWidth: 500,
yAxisWidth: 500,
right: 30,
bottom: 30,
left: 130
}
var center= [
[1,1]
]
/*
* 选择 id 为 demo 的元素
* 设置 width.height 为 700
*/
var svg = d3.select("#demo")
.append("svg")
.attr("width",padding.width)
.attr("height", padding.height)

/*
分别定义 x/y 轴比例尺 xScale
并根据数据来决定比例尺数值中的数据
*/
var xScale = d3.scaleLinear()
.domain([0, 1 * d3.max(center, function (d) {
return d[1]
})])
.range([0, padding.xAxisWidth])

/*
* 定义坐标轴
* ticks
* 自定义刻度的显示方式及格式化刻度
*/
var xAxis = d3.axisBottom(xScale)
/*
* tickSize
* 设置刻度外侧(outer)和内侧(inner)的高度
* -> 需要注意的是在 d3 version3 版本中 tickSize 可以分别设置内侧和外侧的高度,但在 v4中被取消了
*/
.tickSize(3)

d3.select("svg")
.append("g")
.attr("transform","translate(" + padding.left + "," + (padding.height - padding.bottom) + ")")
.call(xAxis)

tickSizeInner & tickSizeOuter


tickSizeInner 与 tickSizeOuter 分别可以来进行对刻度的外侧(outer)和内侧(inner)来对其设置高度

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
var padding = {
width: 700,
height: 700,
xAxisWidth: 500,
yAxisWidth: 500,
right: 30,
bottom: 30,
left: 130
}
var center= [
[1,1]
]
/*
* 选择 id 为 demo 的元素
* 设置 width.height 为 700
*/
var svg = d3.select("#demo")
.append("svg")
.attr("width",padding.width)
.attr("height", padding.height)

/*
分别定义 x/y 轴比例尺 xScale
并根据数据来决定比例尺数值中的数据
*/
var xScale = d3.scaleLinear()
.domain([0, 1 * d3.max(center, function (d) {
return d[1]
})])
.range([0, padding.xAxisWidth])

/*
* 定义坐标轴
* ticks
* 自定义刻度的显示方式及格式化刻度
*/
var xAxis = d3.axisBottom(xScale)
/*
* tickSizeInner & tickSizeOuter
* 设置刻度外侧(outer)和内侧(inner)的高度
*/
.tickSizeInner(2)
.tickSizeOuter(5)

d3.select("svg")
.append("g")
.attr("transform","translate(" + padding.left + "," + (padding.height - padding.bottom) + ")")
.call(xAxis)
⬅️ Go back